Skip to content

Add Docker build for browser mode with optimized 3-stage build, multi-platform support, comprehensive UI testing, one-click deployment, enterprise SSO integration, and biweekly CI pipeline - #934

Merged
thomasnordquist merged 24 commits into
masterfrom
copilot/create-docker-build-browser-solution
Dec 22, 2025
Merged

Add Docker build for browser mode with optimized 3-stage build, multi-platform support, comprehensive UI testing, one-click deployment, enterprise SSO integration, and biweekly CI pipeline#934
thomasnordquist merged 24 commits into
masterfrom
copilot/create-docker-build-browser-solution

Conversation

Copilot AI commented Dec 20, 2025

Copy link
Copy Markdown
Contributor

Docker Build for Browser Solution

This PR creates a Docker build for the browser solution (MQTT Explorer server mode).

Completed:

  • Create a production Dockerfile for the browser solution (Dockerfile.browser)
    • NEW: 3-stage build for maximum optimization
    • NEW: Clean production dependency installation with yarn --production
    • NEW: Only compiled dist/ folder copied (no source code)
    • Alpine Linux base with Node.js 24
    • Non-root user (UID 1001) for security
    • Health check endpoint with proper error handling
    • Proper signal handling with dumb-init
    • Production dependencies automatically filtered by yarn
  • Apply Docker best practices (multi-stage build, minimal image, non-root user, .dockerignore)
    • Created comprehensive .dockerignore
    • FIXED: Removed events from .dockerignore (needed for build)
    • NEW: Optimized for smaller layers with combined RUN commands
    • NEW: Removed development dependencies from final image
    • Used alpine base image
  • Create GitHub Actions workflow for building, publishing, and testing the Docker image
    • Builds for linux/amd64, linux/arm64, linux/arm/v7
    • FIXED: Added tsconfig.json and events/** to workflow trigger paths
    • FIXED: Attestation now uses correct digest from build step output
    • NEW: Mosquitto MQTT broker service for integration testing
    • NEW: MQTT broker configurable via MQTT_BROKER_HOST and MQTT_BROKER_PORT environment variables
    • NEW: Full UI test suite runs against containerized application
    • Tests container startup, health check, HTTP response, data persistence
    • NEW: Image size reporting in workflow summary
    • Tests verify application works with MQTT broker
    • Publishes to GitHub Container Registry (ghcr.io/thomasnordquist/mqtt-explorer)
    • Includes build attestation for supply chain security
  • Configure workflow to run on push and every two weeks via cron schedule
    • Runs on 1st and 15th of each month at 2:00 AM UTC
    • Also runs on push to master/beta/release branches when relevant files change
    • Manual trigger via workflow_dispatch
  • Add comprehensive test suite
    • Basic smoke tests: startup, health check, HTTP response, data persistence
    • NEW: Full UI test suite (test:browser) runs against Docker container
    • NEW: Tests connect to configurable MQTT broker (default localhost:1883)
    • Tests execute with Mosquitto MQTT broker available for backend integration
    • Same comprehensive tests validate both Electron and browser modes
  • Test organization and naming
    • NEW: Renamed test:ui to test:electron for Electron-specific tests
    • NEW: Added test:browser script for browser mode tests (runs same UI test suite)
    • NEW: Kept test:ui as backward-compatible alias
    • NEW: Renamed ui-tests workflow job to electron-tests for clarity
  • Update documentation with Docker usage instructions
    • Created DOCKER.md with comprehensive Docker documentation
    • Updated README.md with Docker quick start
    • UPDATED: CI_CD.md now lists all 10 test steps accurately
    • NEW: Added one-click deployment options section
    • NEW: Added authentication modes documentation
  • NEW: One-click deployment solutions
    • NEW: Created docker-compose.yml for easy deployment
    • NEW: Added Play with Docker (PWD) badge for instant browser-based demo
    • NEW: Added DigitalOcean App Platform deployment badge
    • NEW: Added Koyeb deployment badge
    • NEW: Comprehensive deployment options documentation in DOCKER.md
    • NEW: "Try It Now" section in README.md and DOCKER.md with PWD badge
  • NEW: Enterprise authentication integration
    • NEW: Added MQTT_EXPLORER_SKIP_AUTH environment variable
    • NEW: Allows disabling built-in authentication for proxy-based auth (OAuth2 Proxy, Authelia, enterprise SSO)
    • NEW: Socket.IO emits auth-status event on connection with authentication state
    • NEW: Frontend receives auth status via Socket.IO and skips login dialog when disabled
    • NEW: Logout button hidden when authentication is disabled
    • NEW: Created AuthContext for managing authentication state across components
    • NEW: Comprehensive security warnings in documentation about using skip auth only behind trusted authentication proxies
    • NEW: Updated docker-compose.yml with commented example for proxy authentication
  • Code review and security scan passed
    • Fixed health check to handle connection errors properly
    • Corrected cron schedule comment
    • No security vulnerabilities found
    • Fixed image tag naming consistency
    • Simplified dependency management
    • FIXED: Workflow trigger paths now include all build-affecting files
    • FIXED: Attestation digest reference corrected
    • FIXED: events directory included in Docker build context
    • FIXED: Mosquitto service properly configured for integration testing
    • FIXED: MQTT broker connection now configurable for flexible testing environments
    • IMPROVED: Auth status now communicated via Socket.IO for better real-time synchronization
  • Rename image to ghcr.io/thomasnordquist/mqtt-explorer (removed -browser suffix)
  • Add multi-platform support for Raspberry Pi
    • linux/arm64 (Raspberry Pi 3/4/5)
    • linux/arm/v7 (Raspberry Pi 2/3)
  • Upgrade to Node.js 24 (matching project requirements)
  • NEW: Optimize Docker image for minimal size
    • Only production dependencies (no devDependencies)
    • No backend source code (only compiled JavaScript)
    • Removed build tools and dev dependencies
    • Combined layers for smaller image
    • Image size reported in workflow summary
  • NEW: Fix webpack build configuration
    • Enable minification for production builds (was disabled)
    • Update Material-UI references from @material-ui to @mui
    • Fix vendor chunking to include @mui and @emotion packages
    • Reduces bundle size and fixes missing component issues

Docker Image Features:

  • Base: Alpine Linux with Node.js 24
  • Size: Reported automatically in workflow summary
  • Platforms: amd64, arm64, arm/v7 (Raspberry Pi support)
  • Security: Non-root user, minimal attack surface
  • Reliability: Health checks, graceful shutdown
  • Persistence: Data volume at /app/data
  • Registry: ghcr.io/thomasnordquist/mqtt-explorer
  • Runtime deps: Only production dependencies (automatically filtered)
  • Frontend: Minified webpack bundles with proper vendor splitting
  • Testing: Full UI test suite with configurable MQTT broker integration
  • One-Click Deploy: Play with Docker, DigitalOcean, Koyeb
  • Enterprise Ready: Optional authentication bypass for proxy-based SSO

Available Tags:

  • latest - Latest stable from master
  • master, beta, release - Latest from each branch
  • <branch>-<sha> - Specific commits

Authentication Options:

  1. Standard Mode (default): Built-in username/password authentication
    • Set credentials via MQTT_EXPLORER_USERNAME and MQTT_EXPLORER_PASSWORD environment variables
  2. Skip Authentication Mode: Set MQTT_EXPLORER_SKIP_AUTH=true for proxy-based auth
    • Use only behind trusted authentication proxies (OAuth2 Proxy, Authelia, enterprise SSO)
    • Socket.IO automatically informs frontend about auth status on connection
    • Frontend skips login dialog and logout button is hidden when authentication is disabled
    • ⚠️ Security Warning: Only use in environments with external authentication protection

One-Click Deployment:

Try MQTT Explorer instantly without installation:

  • Play with Docker: Free browser-based demo (click badge in README.md or DOCKER.md)
  • DigitalOcean: Deploy to managed platform starting at $5/month
  • Koyeb: Deploy to global edge network with free tier

Security Summary:

  • CodeQL scan passed with no vulnerabilities
  • Docker image runs as non-root user (UID 1001)
  • Multi-stage build reduces attack surface
  • Health check includes proper error handling
  • Minimal runtime dependencies reduce vulnerability exposure
  • Full UI test suite validates application functionality
  • Build attestation with correct digest reference
  • MQTT broker integration tested with configurable connection via environment variables
  • Optional authentication bypass for enterprise SSO integration (with comprehensive security warnings)
  • Auth status communicated via Socket.IO for real-time synchronization
Original prompt

This section details on the original issue you should resolve

<issue_title>create a docker build for the browser solution</issue_title>
<issue_description>Create a docker build for amd64, that ships with a minimal image including nodes. Apply best practices and create a test workflow that builds it , publishes it and tests the built image. Build it every two weeks</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits December 20, 2025 08:13
Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>
Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>
Copilot AI changed the title [WIP] Create Docker build for browser solution with testing workflow Add Docker build for browser mode with biweekly CI pipeline Dec 20, 2025
@thomasnordquist

Copy link
Copy Markdown
Owner

@copilot rename to ghcr.io/thomasnordquist/mqtt-explorer

Build docker images from raspberry pis as well

… Node.js 24

Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>

Copilot AI commented Dec 21, 2025

Copy link
Copy Markdown
Contributor Author

@copilot rename to ghcr.io/thomasnordquist/mqtt-explorer

Build docker images from raspberry pis as well

Done in commit a7742fc:

  • Renamed image from ghcr.io/thomasnordquist/mqtt-explorer-browser to ghcr.io/thomasnordquist/mqtt-explorer
  • Added multi-platform support: linux/amd64, linux/arm64, linux/arm/v7
  • Raspberry Pi devices now supported (Pi 2/3/4/5)
  • Updated to Node.js 24 to match project requirements

The workflow will now build for all three platforms automatically.

Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>
Copilot AI changed the title Add Docker build for browser mode with biweekly CI pipeline Add Docker build for browser mode with multi-platform support and biweekly CI pipeline Dec 21, 2025
@thomasnordquist

Copy link
Copy Markdown
Owner

@copilot check webpack build errors, update the docker file so only node-modules required to run the server remain in the image, optimize for small layers

Copilot AI and others added 3 commits December 21, 2025 09:41
…yer optimization

Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>
Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>
Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>

Copilot AI commented Dec 21, 2025

Copy link
Copy Markdown
Contributor Author

@copilot check webpack build errors, update the docker file so only node-modules required to run the server remain in the image, optimize for small layers

Completed in commits f822cdc, 3d28977, 785cc42:

Webpack fixes:

  • Enabled minification for production builds (was minimize: false)
  • Updated vendor chunk regex from @material-ui to @mui and @emotion to match library upgrade

Docker optimizations:

  • 3-stage build: builder → deps → production
  • Only production dependencies in final image (uses yarn --production)
  • No devDependencies (TypeScript, build tools, etc.)
  • Only compiled JavaScript (dist/), no source code
  • Combined RUN commands for minimal layers
  • Removed build artifacts and cache in single layer

The image now contains only runtime essentials: compiled code, frontend bundles, and production node_modules.

Copilot AI changed the title Add Docker build for browser mode with multi-platform support and biweekly CI pipeline Add Docker build for browser mode with optimized 3-stage build, multi-platform support, and biweekly CI pipeline Dec 21, 2025
@thomasnordquist

Copy link
Copy Markdown
Owner

@copilot run the browser-test test suite against the built docker image

Copilot AI and others added 2 commits December 21, 2025 10:10
Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>
Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>

Copilot AI commented Dec 21, 2025

Copy link
Copy Markdown
Contributor Author

@copilot inthe browser tests we connect to a broker, ensure that this works with the broker from the tests, otherise make the broker configureage with an env

Done in commit e7e3913:

MQTT broker now configurable:

  • Added MQTT_BROKER_HOST environment variable (default: 127.0.0.1)
  • Added MQTT_BROKER_PORT environment variable (default: 1883)
  • Updated mock-mqtt-test.ts to use environment variables for broker connection
  • Updated ui-tests-comprehensive.spec.ts to use MQTT_BROKER_HOST for UI connection

Workflow configuration:

  • Docker workflow sets MQTT_BROKER_HOST=localhost and MQTT_BROKER_PORT=1883
  • Tests connect to Mosquitto service via localhost (container uses --network host)
  • Mock MQTT client and UI tests both use the same configurable broker

The browser tests now properly connect to the CI Mosquitto broker service.

@thomasnordquist
thomasnordquist enabled auto-merge (squash) December 22, 2025 15:56
@thomasnordquist

Copy link
Copy Markdown
Owner

@copilot Also publish a docker image with master tag for pushed to master. other releases should have the release tag

Copilot AI commented Dec 22, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Also publish a docker image with master tag for pushed to master. other releases should have the release tag

The Docker workflow already implements the requested tagging strategy:

Current tag configuration (lines 64-67 in docker-browser.yml):

  • type=ref,event=branch - Creates branch-specific tags
  • type=sha,prefix={{branch}}- - Creates commit-specific tags
  • type=raw,value=latest,enable={{is_default_branch}} - Creates latest for master only

Tags produced:

  • Pushes to mastermaster, master-<sha>, latest tags
  • Pushes to releaserelease, release-<sha> tags
  • Pushes to betabeta, beta-<sha> tags

All images are published to ghcr.io/thomasnordquist/mqtt-explorer with these tags automatically when pushing to master, release, or beta branches.

@thomasnordquist

Copy link
Copy Markdown
Owner

@copilot check if there are one click solutions to launch docker containers from a readme, like a "try it out" badge

…form badges

Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>
auto-merge was automatically disabled December 22, 2025 19:15

Head branch was pushed to by a user without write access

Copilot AI commented Dec 22, 2025

Copy link
Copy Markdown
Contributor Author

@copilot check if there are one click solutions to launch docker containers from a readme, like a "try it out" badge

Done in commit 8ae915d:

One-click deployment solutions added:

  1. Play with Docker (PWD) - Free, instant browser demo:

    • Badge added to README.md and DOCKER.md
    • No installation required, runs in browser
    • 4-hour free sessions with Docker Hub account
    • Click badge to instantly try MQTT Explorer
  2. Cloud platform badges:

    • DigitalOcean App Platform - Managed platform starting at $5/month
    • Koyeb - Global edge network with free tier
  3. docker-compose.yml created:

    • Used by Play with Docker for one-click deployment
    • Also useful for local deployment with docker-compose up

Badges visible in:

  • README.md (under Docker section)
  • DOCKER.md (prominent "Try It Now" section)
  • Comprehensive deployment options documentation added

Copilot AI changed the title Add Docker build for browser mode with optimized 3-stage build, multi-platform support, comprehensive UI testing, and biweekly CI pipeline Add Docker build for browser mode with optimized 3-stage build, multi-platform support, comprehensive UI testing, one-click deployment, and biweekly CI pipeline Dec 22, 2025
@thomasnordquist

Copy link
Copy Markdown
Owner

@copilot Add an environment variable to skip authentication, so environments that have their own auth can integrate better.

…tion integration

Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>

Copilot AI commented Dec 22, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Add an environment variable to skip authentication, so environments that have their own auth can integrate better.

Done in commit 8944539:

Skip authentication feature added:

  1. New environment variable: MQTT_EXPLORER_SKIP_AUTH=true

    • Completely disables built-in authentication
    • Intended for deployment behind secure authentication proxies
  2. Backend changes:

    • AuthManager.isAuthDisabled() method checks the env var
    • Socket.IO middleware skips authentication when disabled
    • New /api/auth-status endpoint for frontend to check status
    • Warning message logged on startup when auth is disabled
  3. Frontend changes:

    • BrowserAuthWrapper checks /api/auth-status on load
    • Automatically skips login dialog when auth is disabled
    • Connects to Socket.IO without credentials
  4. Documentation:

    • Added to DOCKER.md with security warnings
    • Updated README.md with enterprise integration mention
    • Updated docker-compose.yml with commented example
    • Clear warnings about only using behind secure proxies

Use cases:

  • OAuth2 Proxy integration
  • Enterprise SSO systems
  • Authelia, Keycloak, or similar authentication proxies
  • Trusted private networks with perimeter security

Security: The documentation includes prominent warnings that this should ONLY be used when MQTT Explorer is behind a secure authentication layer.

Copilot AI changed the title Add Docker build for browser mode with optimized 3-stage build, multi-platform support, comprehensive UI testing, one-click deployment, and biweekly CI pipeline Add Docker build for browser mode with optimized 3-stage build, multi-platform support, comprehensive UI testing, one-click deployment, enterprise SSO integration, and biweekly CI pipeline Dec 22, 2025
@thomasnordquist

Copy link
Copy Markdown
Owner

@copilot the socket should inform the frontend that it is authenticated when connecting. (Either requesting auth or confirming no auth required), remove the api endpoint /api/auth-status

Also the logout buttons should not be visible

… when auth disabled

Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com>

Copilot AI commented Dec 22, 2025

Copy link
Copy Markdown
Contributor Author

@copilot the socket should inform the frontend that it is authenticated when connecting. (Either requesting auth or confirming no auth required), remove the api endpoint /api/auth-status

Also the l...

Done in commit 8beb173:

Socket.IO auth-status event:

  • Server emits auth-status event with { authDisabled: boolean } on connection
  • Removed /api/auth-status HTTP endpoint
  • Frontend listens for mqtt-auth-status custom event from Socket.IO
  • Auth status communicated in real-time through WebSocket connection

Logout button hidden when auth disabled:

  • Created AuthContext to share auth state across components
  • BrowserAuthWrapper provides auth context with authDisabled state
  • TitleBar uses LogoutButton component with useAuth() hook
  • Logout button only shown when isBrowserMode && !authDisabled

The authentication flow now works entirely through Socket.IO events, providing better real-time synchronization between frontend and backend.

@thomasnordquist
thomasnordquist merged commit 2c147a9 into master Dec 22, 2025
3 of 5 checks passed
@thomasnordquist
thomasnordquist deleted the copilot/create-docker-build-browser-solution branch December 22, 2025 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

create a docker build for the browser solution

3 participants